#include "FWDirectShow.h"



FWDirectShow::FWDirectShow(void)
{
	this->_graphBuilder = NULL;
	this->_mediaControl = NULL;
	this->_mediaEventEx = NULL;
	this->_mediaSeeking = NULL;
	this->_isPlaying = false;
}


FWDirectShow::~FWDirectShow(void)
{
}

void FWDirectShow::initialize()
{
	//create instance of graph builder
	CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void**)&this->_graphBuilder);
	if(!this->_graphBuilder)
	{
		MessageBox(NULL, "can't create graph builder", "ERROR", MB_OK);
		return;
	}
	//get reference to interface
	this->_graphBuilder->QueryInterface(IID_IMediaControl, (void**)&this->_mediaControl);
	this->_graphBuilder->QueryInterface(IID_IMediaSeeking, (void**)&this->_mediaSeeking);
	this->_graphBuilder->QueryInterface(IID_IMediaEventEx, (void**)&this->_mediaEventEx);
	if(!this->_mediaControl || !this->_mediaEventEx || !this->_mediaSeeking)
	{
		MessageBox(NULL, "can't query interface", "ERROR", MB_OK);
		return;
	}
	this->_isPlaying = false;
}

void FWDirectShow::load(LPCTSTR fileName)
{
	WCHAR* wfileName = new WCHAR[256];
	//convert fileName to WCHAR*
	mbstowcs(wfileName, fileName, 256);
	//builds a filter graph
	HRESULT hr = this->_graphBuilder->RenderFile(wfileName, NULL);
	if(!FAILED(hr))
	{
		this->_isReady = true;
		if(_mediaSeeking)
		{
			_mediaSeeking->SetTimeFormat(&TIME_FORMAT_MEDIA_TIME);
			_mediaSeeking->GetDuration(&_duration);
			_duration = _duration;
		}
	}
	this->_isPlaying = false;	
}

void FWDirectShow::playSoundTrack()
{
	if(this->_mediaControl && this->_isReady)
	{		
		LONGLONG a = _duration;
		LONGLONG b = getCurrentPosition();	
		//play again
		if(a == b)
		{
			b = 0;
			setPosition(&b, &a, true);
		}
		this->_mediaControl->Run();
	}	
}

void FWDirectShow::pause()
{
	if(this->_mediaControl != NULL)
	{
		if(this->_isPlaying)
		{
			this->_mediaControl->Pause();
			this->_isPlaying = false;
		}
	}
}

void FWDirectShow::resume()
{
	if (this->_mediaControl != NULL)
	{
		if(!this->_isPlaying)
		{
			this->_mediaControl->Run();
			this->_isPlaying = true;
		}
	}
}

void FWDirectShow::stop()
{
	if (this->_mediaControl != NULL)
	{
		if (this->_isPlaying)
		{
			this->_mediaControl->Stop();
			this->_isPlaying = false;
		}
	}
}

void FWDirectShow::setPosition(__int64* pCurrent, __int64* pStop, bool absolutePositioning)
{
	if (_isReady && _mediaSeeking)
	{
		DWORD flag = 0;
		if(absolutePositioning)
			flag = AM_SEEKING_AbsolutePositioning | AM_SEEKING_SeekToKeyFrame;
		else
			flag = AM_SEEKING_RelativePositioning | AM_SEEKING_SeekToKeyFrame;
		HRESULT hr = _mediaSeeking->SetPositions(pCurrent, flag, pStop, flag);
		if(!FAILED(hr))
			int x = 1;
	}
}

__int64 FWDirectShow::getCurrentPosition()
{
	if(_isReady && _mediaSeeking)
	{
		__int64 currentPos = -1;
		HRESULT hr = _mediaSeeking->GetCurrentPosition(&currentPos);
		if(!FAILED(hr))
			return currentPos;
	}
	return -1;
}

void FWDirectShow::playSoundEffect()
{
	if(this->_mediaControl && this->_isReady)
	{
		//play from start pos
		LONGLONG a = _duration;
		LONGLONG b = 0;		
		setPosition(&b, &a, true);		
		this->_mediaControl->Run();
	}	
}
